﻿<cfscript>
/** 
* Math for Senate Frameworks
* 
* @hint "Math for Senate Frameworks" 
*/ 

component 
	displayname="public.service.util.senateMathAdvice" 
	output=false 
	{
	
	/**
	* @hint "初始化对象"
	*/
	public public.service.util.senateMathAdvice function init() output=false {
		return this;
	}
	
	/**
	* @hint "将10位ISBN号码升级至13位"
	* 
	* @isbn10 "ISBN 10位代码"
	*/
	public string function upgradeISBN( required string isbn10 ) output=false {
		
		var isbn13 = "978" & left(arguments.isbn10, 9);
		var check = 0;
		
		if ( isNumeric(isbn13) ) {
			
			for (i = 0; i lt 12; i+=2) {
				check += int(mid(isbn13, i+1, 1));
			}
			for (i = 1; i lt 12; i+=2) {
				check += 3 * int(mid(isbn13, i+1, 1));
			}
			
			return isbn13 & ( (10-check mod 10) mod 10 );
			
		}
		else {
			return arguments.isbn10;
		}
	}
	
	/**
	* @hint "检验ISBN号码"
	* 
	* @isbnString "ISBN 代码"
	*/
	public boolean function isISBN( required string isbnString ) output=false {
		
		var isbnNumber = uCase(replace(trim(arguments.isbnString), "-", "", "ALL"));
		
		var i = 0;
		var check = 0;
		
		/* 首先使用正则检测ISBN */
		if ( refind("^(97(8|9))?\d{9}(\d|X)$", isbnNumber) ) {
			
			/* ISBN-13 */
			if ( len(isbnNumber) == 13 and isNumeric(isbnNumber) ) {
				
				for (i = 0; i lt 13; i+=2) {
					check += int(mid(isbnNumber, i+1, 1));
				}
				for (i = 1; i lt 12; i+=2) {
					check += 3 * int(mid(isbnNumber, i+1, 1));
				}
				
				if ( check % 10 == 0 ) {
					return true;
				}
				
			}
			
			/* ISBN-10 */
			if ( len(isbnNumber) == 10 and isNumeric( replace(isbnNumber, "X", "") )) {
				
				for ( i=0; i lt 10; i++ ) {
					check += int( replace(mid(isbnNumber, i+1, 1), "X", "10") ) * (10-i);
				}
				
				if (check % 11 == 0) {
					return true;
				}
				
			}
			
		}
		
		return false;
	}
	
	/**
	* @hint "将教学周某一天转换为日期字符串"
	* 
	* @termStartString "开学日期"
	* @taskWeek "教学周"
	* @taskWeekDay "星期几"
	*/
	public string function revertTaskWeekDay( required string termStartString, numeric taskWeek, numeric taskWeekDay ) output=false {
		
		var theDate = createDate( left(arguments.termStartString, 4), mid(arguments.termStartString, 5, 2), right(arguments.termStartString, 2) );
		
		/* 处理教学周 */
		if ( arguments.taskWeek gt 0 ) {
			theDate = dateAdd( "ww", (arguments.taskWeek-1), theDate );
		}
		if ( arguments.taskWeek lt 0 ) {
			theDate = dateAdd( "ww", arguments.taskWeek, theDate );
		}
		
		/* 处理教学周内日期 */
		if ( arguments.taskWeekDay gte 1 and arguments.taskWeekDay lte 7 ) {
			theDate = dateAdd( "d", (arguments.taskWeekDay-1), theDate );
		}

		
		return DateFormat(theDate, "YYYYMMDD");
	}
	
	/**
	* @hint "计算教学周"
	* 
	* @termStartString "开学日期"
	* @dateString "指定日期"
	*/
	public numeric function convertTaskWeek( required string termStartString, string dateString ) output=false {
		
		var taskWeek = 0;
		
		var termDateStart = createDate( left(arguments.termStartString, 4), mid(arguments.termStartString, 5, 2), right(arguments.termStartString, 2) );
		var theDate = createDate( left(arguments.dateString, 4), mid(arguments.dateString, 5, 2), right(arguments.dateString, 2) );
		
		var weekOff = dateDiff("ww", termDateStart, theDate);
		
		if ( weekOff gt 0) {
			taskWeek = weekOff + 1;
		}
		else if ( weekOff eq 0 and theDate gte termDateStart ) {
			taskWeek = 1;
		}

		return taskWeek;
	}
	
	/**
	* @hint "将上课时间转换为中文"
	* 
	* @taskTime "排课时间字符串"
	*/
	public string function convertTaskTime( required string taskTime ) output=false {
		
		var strChinese = "";
		var taskTimes = listToArray(arguments.taskTime, ",");
		var tTime = "";
		var timeSet = [];
		
		if ( arrayLen(taskTimes) ) {
			
			for (tTime in taskTimes) {
				
				if ( tTime eq "-" ) {
					strChinese = "-";
				}
				else {
					
					timeSet = listToArray(tTime, "@-");

					if (arrayLen(timeSet) eq 3) {
					
						switch (timeSet[3]) {
							case "1":
								strChinese = listAppend(strChinese, convertWeekDayToChinese(timeSet[1]) & convertLectureIdxToChinese2(timeSet[3],timeSet[2]), ",");
								break;
							case "2":
							case "3":
								strChinese = listAppend(strChinese, convertWeekDayToChinese(timeSet[1]) & convertLectureIdxToChinese2(timeSet[3],timeSet[2]), ",");
								break;
							case "4":
							case "5":
								strChinese = listAppend(strChinese, convertWeekDayToChinese(timeSet[1]) & convertLectureIdxToDayPart(timeSet[2]), ",");
								break;
							case "8":
								strChinese = listAppend(strChinese, convertWeekDayToChinese(timeSet[1]) & "白天", ",");
								break;
						}
					}
								
				}
			}
			
		} 
		else {
			strChinese = "-";
		}
		
		return strChinese;
	}
	
	/**
	* @hint "判断上课周次序列是否重叠"
	* 
	* @weekidx1 "周次序列"
	* @weekidx2 "周次序列"
	*/
	public boolean function isWeekIdxOver( weekidx1, weekidx2 ) output=false {
		var i = 0;
		var w1 = w2 = "0";
		
		for (i=1; i lte len(arguments.weekidx1); i++) {
			
			w1 = mid(arguments.weekidx1, i, 1);
			w2 = mid(arguments.weekidx2, i, 1);
			
			if ( w1 eq w2 and w1 eq "1") {
				return true;
			}
			
		}
		
		return false;
	}
	
	/**
	* @hint "判断上课周次是否重叠"
	* 
	* @week1 "周次"
	* @week2 "周次"
	*/
	public boolean function isWeekOver( week1, week2 ) output=false {
		
		var week1S = int(listFirst(arguments.week1, "-"));
		var week1E = int(listLast(arguments.week1, "-"));

		var week2S = int(listFirst(arguments.week2, "-"));
		var week2E = int(listLast(arguments.week2, "-"));
		
		if (week1E lt week2S or week1S gt week2E) {
			return false;
		}
		else {
			return true;
		}
		
	}
	

	/**
	* @hint "判断上课讲次是否重叠"
	* 
	* @taskTime1 "讲次1" 5@2-3
	* @taskTime2 "讲次2" 4@1-5
	*/
	public boolean function isTaskTimeOver( taskTime1, taskTime2 ) output=false {
		
		/* weekDay @ lecture - length */
		
		if ( listLen( arguments.taskTime1, "@-" ) eq 3 and listLen( arguments.taskTime2, "@-" ) eq 3 ) {
			
			/* 是否同一天 */
			if ( int( listFirst( arguments.taskTime1, "@-" ) ) eq int( listFirst( arguments.taskTime2, "@-" ) ) ) {
				
				/* 判断长度是否交叠 */
				var time1S = convertLectureIdxToCellStart( listGetAt( arguments.taskTime1, 2, "@-" ) );
				var time1E = time1S + listGetAt( arguments.taskTime1, 3, "@-" ) -1;

				var time2S = convertLectureIdxToCellStart( listGetAt( arguments.taskTime2, 2, "@-" ) );
				var time2E = time2S + listGetAt( arguments.taskTime2, 3, "@-" ) -1;
				
				if (time1E lt time2S or time1S gt time2E) {
					return false;
				}
				else {
					return true;
				}

			}
			
		}
		
		return false;
	}
	

	/**
	* @hint "将考试周次转换为周次序列"
	* 
	* @weekEX "周次"
	*/
	public string function convertExamWeekIdx( required numeric weekEX ) output=false {
		
		var weekArray = [];
		for ( var i=1; i lte 25; i++ ) { arrayAppend(weekArray, 0); }
		
		if ( arguments.weekEX gt 0 ) {
			arraySet( weekArray, arguments.weekEX, arguments.weekEX, 1 );
		}
		
		if ( arguments.weekEX eq -1 ) {
			arraySet( weekArray, 25, 25, 1 );
		}
		
		return arrayToList( weekArray, "" );
	}
	
	/**
	* @hint "将授课周次转换为周次序列"
	* 
	* @weekSE "周次"
	*/
	public string function convertWeekIdx( required string weekSE ) output=false {
		
		var weekArray = [];
		for ( var i=1; i lte 25; i++ ) { arrayAppend(weekArray, 0); }
		
		var taskWeek = listToArray(arguments.weekSE, "-");
		
		if ( taskWeek[2] gte taskWeek[1] ) {
			arraySet( weekArray, taskWeek[1], taskWeek[2], 1 );
		}

		return arrayToList( weekArray, "" );
	}

	/**
	* @hint "将讲次转换为节次起点"
	* 
	* @lecIdx "讲次"
	*/
	public numeric function convertLectureIdxToCellStart( required string lecIdx ) output=false {

		switch (arguments.lecIdx) {
			case '1': 
			case 'S': /* 上午 */
			case 'B': /* 白天 */
			case 'Q': /* 全天 */
				return 1;
			case '2': 
				return 3;
			case '3': 
			case 'X': /* 下午 */
				return 6;
			case '4': 
				return 8;
			case '5': 
			case 'W': /* 晚上 */
				return 11;
			case '6': 
				return 13;
			case 'M': /* 早自习 */
				return 20;
			case 'E': /* 晚自习 */
				return 30;
			case 'N': /* 中午 */
				return 40;
		}
		
	}
	
	/**
	* @hint "将讲次转换为可排节次"
	* 
	* @lecIdx "讲次"
	*/
	public array function convertLectureIdxToCellLength( required string lecIdx ) output=false {

		switch (arguments.lecIdx) {
			case '1': 
				return [1,2,3,4,5,8];
			case '2':
				return [1,2];
			case '5': 
				return [1,2,3,4];
			case '3': 
				return [1,2,3,4];
			case '4': 
			case '6': 
				return [1,2];
		}
	}
	
	/**
	* @hint "将讲次转换为当天时间段"
	* 
	* @lecIdx "讲次"
	*/
	public string function convertLectureIdxToDayPart( required string lecIdx ) output=false {

		switch (arguments.lecIdx) {
			case '1': 
			case '2':
				return "上午";
			case '3': 
			case '4': 
				return "下午";
			case '5': 
			case '6': 
				return "晚上";
			case 'M': 
				return "早自习";
			case 'E': 
				return "晚自习";
			case 'N': 
				return "中午";
		}
		
		return '';
	}

	/**
	* @hint "将 DayOfWeek 转换为中国星期几"
	* 
	* @weekDay "Coldfusion Day of Week"
	*/
	public string function convertDayOfWeekToWeekDay( required numeric weekDay ) output=false {
		
		switch (arguments.weekDay) {
			case '1': return "6";
			case '2': return "1";
			case '3': return "2";
			case '4': return "3";
			case '5': return "4";
			case '6': return "5";
			case '7': return "6";
		}
		
		return '';
	}

	/**
	* @hint "将星期某日为中文描述"
	* 
	* @weekDay "星期几"
	*/
	public string function convertWeekDayToChinese( required string weekDay ) output=false {

		switch (arguments.weekDay) {
			case '1': return "周一";
			case '2': return "周二";
			case '3': return "周三";
			case '4': return "周四";
			case '5': return "周五";
			case '6': return "周六";
			case '7': return "周日";
		}
		
		return '';
	}
	
	/**
	* @hint "将讲次转换为中文描述"
	* 
	* @lecIdx "讲次"
	*/
	public string function convertLectureIdxToChinese( required string lecIdx ) output=false {
		
		switch (arguments.lecIdx) {
			case '1': return "一二节";
			case '2': return "三四节";
			case '3': return "五六节";
			case '4': return "七八节";
			case '5': return "10-11节";
			case '6': return "第六讲";
			case 'M': return "早自习";
			case 'E': return "晚自习";
			case 'N': return "中午";
			case 'S': return "上午";
			case 'X': return "下午";
			case 'W': return "晚上";
			case 'B': return "白天";
			case 'Q': return "全天";
		}
		
		return '';
	}
	
	/**
	* @hint "将讲次转换为中文描述"  - "针对海外学院1个节次和3个节次特殊情况进行单独计算"
	* @timeSet "节次"
	* @lecIdx "讲次"
	*/
	public string function convertLectureIdxToChinese2(required string timeSet, required string lecIdx ) output=false {
		writeLog( text=arguments.timeSet );
		if( arguments.timeSet eq '1' ){
			
			switch (arguments.lecIdx) {
				case '1': return "第一节";
				case '2': return "第三节";
				case '3': return "第五节";
				case '4': return "第七节";
				case '5': return "第十节";
				case '6': return "第六讲";
				case 'M': return "早自习";
				case 'E': return "晚自习";
				case 'N': return "中午";
				case 'S': return "上午";
				case 'X': return "下午";
				case 'W': return "晚上";
				case 'B': return "白天";
				case 'Q': return "全天";
			}	
		}else if( arguments.timeSet eq '3'){
			
			switch (arguments.lecIdx) {
				case '1': return "一二三节";
				case '2': return "第三节";
				case '3': return "五六七节";
				case '4': return "第七节";
				case '5': return "九十十一节";
				case '6': return "第六讲";
				case 'M': return "早自习";
				case 'E': return "晚自习";
				case 'N': return "中午";
				case 'S': return "上午";
				case 'X': return "下午";
				case 'W': return "晚上";
				case 'B': return "白天";
				case 'Q': return "全天";
			}					
		}
		
		switch (arguments.lecIdx) {
			case '1': return "一二节";
			case '2': return "三四节";
			case '3': return "五六节";
			case '4': return "七八节";
			case '5': return "10-11节";
			case '6': return "第六讲";
			case 'M': return "早自习";
			case 'E': return "晚自习";
			case 'N': return "中午";
			case 'S': return "上午";
			case 'X': return "下午";
			case 'W': return "晚上";
			case 'B': return "白天";
			case 'Q': return "全天";
		}
		
		return '';
	}
	
	/**
	* @hint "将考试场次转换为中文描述"
	* 
	* @lecIdx "考试场次"
	*/
	public string function convertExamIdxToChinese( required string lecIdx ) output=false {

		switch (arguments.lecIdx) {
			case '1': return "第一场";
			case '2': return "第二场";
			case '3': return "第三场";
			case '4': return "第四场";
			case '5': return "第五场";
		}
		
		return '';
	}
	
	/**
	* @hint "将学期转换为中文描述"
	* 
	* @termIdx "学期序列"
	*/
	public string function convertTermIdxToChinese( required string termIdx ) output=false {

		switch (arguments.termIdx) {
			/*case 'S1': return "第一学年暑假";
			case 'S2': return "第二学年暑假";
			case 'S3': return "第三学年暑假";
			case '01': return "第一学期";
			case '02': return "第二学期";
			case '03': return "第三学期";
			case '04': return "第四学期";
			case '05': return "第五学期";
			case '06': return "第六学期";
			case '07': return "第七学期";
			case '08': return "第八学期";
			case '09': return "第九学期";
			case '10': return "第十学期";
			case '11': return "第十一学期";
			case '12': return "第十二学期";
			case '13': return "第十三学期";
			case '14': return "第十四学期";
			case '15': return "第十五学期";
			case '16': return "第十六学期";*/
			case '01': return "1秋";
			case '02': return "1春";
			case '03': return "2秋";
			case '04': return "2春";
			case '05': return "3秋";
			case '06': return "3春";
			case '07': return "4秋";
			case '08': return "4春";
		}
		
		return '';
	}
	
	/**
	* @hint "将学年转换为中文描述"
	* 
	* @termYear "学年"
	*/
	public string function convertTermYearToChinese( required string termYear ) output=false {
		
		switch (arguments.termYear) {
			case 1: return "第一学年";
			case 2: return "第二学年";
			case 3: return "第三学年";
			case 4: return "第四学年";
			case 5: return "第五学年";
			case 6: return "第六学年";
			case 7: return "第七学年";
			case 8: return "第八学年";
		}
		
		return '';
	}

	/**
	* @hint "将第N学年转换为可用该学年的学期序列"
	* 
	* @termYear "学年"
	*/
	public array function convertTermYearToSchemaTermIdxArray( required string termYear ) output=false {
		
		switch (arguments.termYear) {
			case 1: return ['01','02','S1'];
			case 2: return ['03','04','S2'];
			case 3: return ['05','06','S3'];
			case 4: return ['07','08','S4'];
			case 5: return ['09','10','S5'];
			case 6: return ['11','12','S6'];
			case 7: return ['13','14','S7'];
			case 8: return ['15','16','S8'];
		}
		
		return [];
	}
	
	/**
	* @hint "根据年级的开课学期, 将当前学期序列转换为学年学期"
	* 
	* @termIndex "学期序"
	* @grade "年级"
	* @termStart "起始学期"
	*/
	public array function convertTermIdxToAcademicTermYear( required string termIndex, required string grade, required string termStart ) output=false {
		
		var academic = arrayNew(1);
		
		if (arguments.termStart eq 1) {
			if (isNumeric(arguments.termIndex)) {
				/* 01,02...15,16 */
				academic[1] = (arguments.grade + round(arguments.termIndex/2) - 1) & "-" & (arguments.grade + round(arguments.termIndex/2));
				academic[2] = 2 - arguments.termIndex mod 2;
			}
			else {
				/* S1, S2.. S8 */
				academic[1] = (arguments.grade + right(arguments.termIndex,1) - 1) & "-" & (arguments.grade + right(arguments.termIndex,1));
				academic[2] = 3;
			}
		}
		else {
			if (isNumeric(arguments.termIndex)) {
				/* 01,02...15,16 */
				academic[1] = (arguments.grade + round(arguments.termIndex/2 + 0.5) - 1) & "-" & (arguments.grade + round(arguments.termIndex/2  + 0.5));
				academic[2] = 1 + arguments.termIndex mod 2;
			}
			else {
				/* S1, S2.. S8 */
				academic[1] = (arguments.grade + right(arguments.termIndex,1)) & "-" & (arguments.grade + right(arguments.termIndex,1) + 1);
				academic[2] = 3;
			}
		}
		
		return academic;
	}
	
	/**
	* @hint "将学期序列,转换为第N学年"
	* 
	* @termIndex "学期序"
	*/
	public string function convertTermIdxToTermYear( required string termIndex ) output=false {
		
		var termYear = "";
		
		if (isNumeric(arguments.termIndex)) {
			/* 01=1, 02=1, 03=2, 04=2 第几学期 */
			termYear = round(arguments.termIndex/2);
		}
		else {
			/* S1=1, S2=2, S3=3, S4=4  S[N] 第几年的夏季小学期*/
			termYear = right(arguments.termIndex, 1);
		}
		
		return termYear;
	}

	/**
	* @hint "根据准考证号读取考试时间"
	* 
	* @sn "准考证号"
	*/
	public string function getCETRound( required string sn ) output=false {
		
		var cetRound = "";
		
		if ( len(arguments.sn) eq 15 ) {
			
			cetRound = "20" & mid(arguments.sn, 7, 2) & " 年 ";
			
			if ( mid(arguments.sn, 9, 1) eq "1" ) {
				cetRound = cetRound & "6 月";
			}
			if ( mid(arguments.sn, 9, 1) eq "2" ) {
				cetRound = cetRound & "12 月";
			}
			

		}
		
		return cetRound;
		
	}

	/**
	* @hint "将整数平均分为指定份数, 并返回数组"
	* 
	* @dividend "总数"
	* @divider "分割分数"
	*/
	public array function divide( required numeric dividend, required numeric divider ) output=false {
		
		var divisor = [];
		var i = 1;
		var remainder = arguments.dividend % arguments.divider;
		
		while ( i lte arguments.divider ) {
			divisor[i] = int(arguments.dividend / arguments.divider);
			i++;
		}
		
		while ( remainder gt 0 ) {
			divisor[remainder] = divisor[remainder]+1;
			remainder--;
		}
		
		return divisor;
	}
	
	
	/**
	* @hint "满意度计算模型"
	* 
	* @sumArray "分级满意度数组 - 由高到低"
	*/
	public numeric function getSatisfactionDegree( required array divisor, numeric radices=2 ) output=false {
		
		var realScroll = 0;
		var maxScroll = 0;
		var i = -1;
		
		for ( var count in divisor ) {
			i++;
			realScroll += radices^( arrayLen(divisor)-i ) * count;
			maxScroll += radices^arrayLen(divisor) * count;
		}
		
		if ( maxScroll gt 0 ) {
			return realScroll/maxScroll;
		}
		
		return 0;
	}
	

}
</cfscript>